import matplotlib.pyplot as plt
import torch
import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler  # 通常使用StandardScaler而不是MinMaxScaler

# 加载乳腺癌数据集
data, target = load_breast_cancer(return_X_y=True)

# 转换为二分类问题（例如，恶性和良性）
# 注意：这里我们简单地使用原始标签，因为它们已经是0和1
# 如果你想要根据某个阈值来重新分类，可以在这里添加逻辑
y_binary = target

# 数据标准化
scaler = StandardScaler()
data_scaled = scaler.fit_transform(data)

# 转换为PyTorch张量
x = torch.Tensor(data_scaled)
y = torch.Tensor(y_binary).reshape(-1, 1)

# 划分训练集和测试集
train_x, test_x, train_y, test_y = train_test_split(x, y)

# 定义模型
# 注意：输入特征数量应该与乳腺癌数据集的特征数量相匹配
model = torch.nn.Sequential(
    torch.nn.Linear(in_features=data.shape[1], out_features=1),  # 修改输入特征数量
    torch.nn.Sigmoid()
)

# 损失函数和优化器
loss_fn = torch.nn.BCELoss()
op = torch.optim.RMSprop(params=model.parameters())

# 训练模型
loss_list = []
for i in range(2000):  # 可能需要调整迭代次数
    op.zero_grad()
    h = model(train_x)
    loss = loss_fn(h, train_y)  # 挤压以匹配标量输出
    loss_list.append(loss.item())
    loss.backward()
    op.step()
    if i % 100 == 0:
        print(f'Loss at iteration {i}: {loss.item()}')

# 测试模型
predict = model(test_x)
y_predict = (predict > 0.5).int()
acc = (y_predict == test_y).float().mean().item()  # 使用.item()来获取Python标量
print(f'Accuracy: {acc}')
